﻿using UnityEngine;
using System.Collections;

public class GameController : MonoBehaviour {
	//static references to this class, and to the player class.
	public static GameController gc;
	public static PlayerController player;
	//refernce to the AStar Script, 2D gridcell array for the board, and the boards height and width.
	public AStar astar;
	public GridCell[,] board;
	public int boardWidth;
	public int boardHeight;
	//not currently in use
	public int[,] navBoard;
	//booleans for displaying the path using the line renderer, and statistics.
	public bool showPath;
	public bool showStatInfo;
	//a reference to the line renderer attached to the same game object as gamecontroller.
	public LineRenderer lineRenderer;
	//a reference to the prefabs for the grid cells
	public GameObject pathableGround;
	public GameObject unpathableGround;
	//references for the different gui text options
	public GUIText timeToCalculateText;
	public GUIText nodesExpandedText;
	public GUIText nodesExploredText;
	//references to the gameobjects for the warning message text alerts.
	public GameObject clickedOnNonWalkableTerrainGameObject;
	public GameObject noPathCouldBeFoundGameObject;

	public float percentageUnpathable;

	// Use this for initialization. Awake is called before start.
	void Awake () {
		gc = this;
		Debug.Log(boardWidth + ", " + boardHeight);
		navBoard = new int[boardHeight,boardWidth];
		initializeBoard();
		player = GameObject.Find("Player").GetComponent<PlayerController>();
		lineRenderer = GetComponent<LineRenderer> ();
	}

	void initializeBoard(){
		/*
		 * Old Static Board Code
		 * 
		int i = 0;
		int j = 0;
		if(boardWidth == 0)
			boardWidth = 17;
		if(boardHeight == 0)
			boardHeight = 10;
		board = new GridCell[boardWidth, boardHeight];
		foreach(GameObject myObject in GameObject.FindGameObjectsWithTag("gridcell")){
			GridCell gridCell = myObject.GetComponent<GridCell>();
			board[i,j] = gridCell;
			gridCell.boardPosition = new Vector2(i,j);
			i++;
			if(i > boardWidth - 1){
				i=0;
				j++;
			}
			gridCell.transform.position = new Vector3(gridCell.boardPosition.x + .5f, gridCell.boardPosition.y + .5f, gridCell.transform.position.z) - new Vector3(boardWidth/2.0f, boardHeight/2.0f, 0f);
		}
		*/
		//construct the board.
		if(boardWidth == 0)
			boardWidth = 17;
		if(boardHeight == 0)
			boardHeight = 10;
		board = new GridCell[boardWidth, boardHeight];
		for(int i = 0; i < boardHeight; i++){
			for(int j = 0; j < boardWidth; j++){
				if(!(j==1 && i==9)){
					Random rnd = new Random();
					//int next = rnd.Next(0,100);
					float next = Random.Range(0,100);
					//GridCell gridCell;
					GameObject myTransform;
					if(next > percentageUnpathable){
						myTransform = Instantiate(pathableGround) as GameObject;
					}
					else{
						myTransform = Instantiate(unpathableGround) as GameObject;
					}
					GridCell gridCell = myTransform.GetComponent<GridCell>();
					board[j,i] = gridCell;
					gridCell.boardPosition = new Vector2(j,i);
					gridCell.transform.position = new Vector3(gridCell.boardPosition.x + .5f, gridCell.boardPosition.y + .5f, gridCell.transform.position.z) - new Vector3(boardWidth/2.0f, boardHeight/2.0f, 0f);
				}
			}
		}

	}
	//sets the players destination grid cell
	public void setPlayerTarget(Vector2 targetGridPosition, GridCell targetGrid){
		player.clearPath();
		resetGameBoard();
		player.destinationGridCell = targetGrid;
		player.myPath = astar.calculatePath();
		//player.printPath(player.myPath);
		player.destinationGrid = targetGridPosition;
	}
	//resets the game board to ready it for the next destination grid cell.
	public void resetGameBoard(){
		for(int i = 0; i < boardWidth; i++){
			for(int j = 0; j < boardHeight; j++){
				board[i,j].fValue = 9001;
				board[i,j].gValue = 0;
				board[i,j].hValue = 0;
				board[i,j].parentGridCell = null;
			}
		}
	}
	//function for updating the Stats Text with the values calculated for the last click.
	public void updateStatGuiText(string time, string nodesExpanded, string nodesExpandedOn){
		timeToCalculateText.text = "Time To Calculate Path: " + time + " ms";
		nodesExpandedText.text = "Total Nodes Expanded(Open List): " + nodesExpanded;
		nodesExploredText.text = "Nodes Expanded On(Closed List): " + nodesExpandedOn;
	}
	//function for displaying the restart level button. Use to generate a new random board.
	void OnGUI(){
		if(GUI.Button(new Rect(Screen.width-Screen.width/6.0f, Screen.height-Screen.height/6.0f, Screen.width/6.0f, Screen.height/6.0f), "Reload Level")){
			Application.LoadLevel("grid1");
		}
		string useBFSText = astar.useBestFirstSearch ? "Use A*" : "Use BFS";
		if(GUI.Button(new Rect(Screen.width-2*Screen.width/6.0f, Screen.height-Screen.height/6.0f, Screen.width/6.0f, Screen.height/6.0f), useBFSText)){
			astar.useBestFirstSearch = !astar.useBestFirstSearch;
		}
		string allowDiagonalMovementText = astar.allowDiagonalMovement ? "Diagonal Move Off" : "Diagonal Move On";
		if(GUI.Button(new Rect(Screen.width-3*Screen.width/6.0f, Screen.height-Screen.height/6.0f, Screen.width/6.0f, Screen.height/6.0f), allowDiagonalMovementText)){
			astar.allowDiagonalMovement = !astar.allowDiagonalMovement;
		}
	}
}
